"""
信号验证基类和数据容器定义
"""
from abc import ABC, abstractmethod
from dataclasses import dataclass
from datetime import datetime
from typing import Optional
import pandas as pd


@dataclass
class ValidationContext:
    """
    验证上下文（封装所有需要的信息）
    """
    stock_data: pd.DataFrame        # 股票数据
    current_index: int               # 当前索引
    current_time: datetime           # 当前时间
    sell_reason: str                 # 卖出原因
    liquidity: str                   # 流动性等级: 'high' | 'medium' | 'low'
    sensitivity: str                 # 敏感度等级: 'high' | 'medium' | 'low' | 'normal'
    stock_code: Optional[str] = None # 股票代码
    position_info: Optional[dict] = None  # 持仓信息（用于计算浮亏等）


@dataclass
class ValidationResult:
    """
    验证结果
    """
    passed: bool                     # 是否通过验证
    validator_name: str              # 验证器名称
    details: str                     # 详细信息
    confidence: float = 1.0          # 置信度 0-1
    
    def __str__(self) -> str:
        status = "🟢" if self.passed else "🔴"
        return f"{status} {self.validator_name}: {self.details} (置信度:{self.confidence:.2f})"


class SignalValidator(ABC):
    """
    信号验证器基类（策略模式）
    所有具体的验证器都应该继承这个类
    """
    
    @abstractmethod
    def validate(self, context: ValidationContext) -> ValidationResult:
        """
        验证信号是否可靠
        
        Args:
            context: 验证上下文
            
        Returns:
            ValidationResult: 验证结果
        """
        pass
    
    @abstractmethod
    def get_name(self) -> str:
        """
        获取验证器名称
        
        Returns:
            str: 验证器名称
        """
        pass
    
    def _check_basic_sell_conditions(self, stock_data: pd.DataFrame, index: int) -> bool:
        """
        检查基础卖出条件（可被子类重写）
        
        Args:
            stock_data: 股票数据
            index: 当前索引
            
        Returns:
            bool: 是否满足基础条件
        """
        if index >= len(stock_data):
            return False
            
        try:
            current_data = stock_data.iloc[index]
            
            # 条件：价格低于MA5且量比小于某个值（这里用简化逻辑）
            if 'MA5' in current_data and 'volume_ratio' in current_data:
                return (current_data['close'] < current_data['MA5'] and 
                       current_data['volume_ratio'] < 2.0)
            
            return False
        except Exception:
            return False

